Corpus preparation

We use here data from Media cloud with only title of news. Therfore the program is more simple than in course.

Selection of media

Check of time frequency

Time divisions

We transform the previous data.frame in a data.table format for easier operations of aggregation

News by week

We examine if the distribution is regular by week for the different media of the corpus.

News by weekday

We examine if the distribution is regular by weekday and check in particular the effect of the week-end.

Transform in quanteda corpus

Corpus consisting of 6 documents and 7 docvars.
1128777462 :
"Apprehension on all sides before launch of Irish abortion se..."

1128777446 :
"Toxic legacy taints ANC as it nears 25-year rule in South Af..."

1128795170 :
"Preparations for the Harbin ice and snow festival – in pictu..."

1128795156 :
"'Resign from Facebook': experts offer Mark Zuckerberg advice..."

1128795141 :
"Gender pay gap: 2018 brought transparency – will 2019 bring ..."

1128795146 :
"It's a thong thing: why £16 flip-flops are the shoe of summe..."

Corpus consisting of 103386 documents, showing 3 documents:

       Text Types Tokens Sentences           who       when        day       week      month weekday nbt
 1128777462    10     10         1 en_GBR_guardi 2019-01-01 2019-01-01 2018-12-31 2019-01-01   Mardi  10
 1128777446    12     12         1 en_GBR_guardi 2019-01-01 2019-01-01 2018-12-31 2019-01-01   Mardi  12
 1128795170    11     11         1 en_GBR_guardi 2019-01-01 2019-01-01 2018-12-31 2019-01-01   Mardi  11

Geographical tags

Preparation of data

Load dictonary

We start by loading the last version of the Imageun dictionary and we extract our target language (here : english).

Load corpus

Load tagging function

Geographical annotation

Annotate all entities

check news with maximum state number


    0     1     2     3     4     5 
74382 25149  3512   303    33     7 
who when text states nbstates
1282834562 en_GBR_guardi 2019-05-14 No Iran threat in Syria or Iraq, top British officer says, contradicting united states IRN SYR IRQ GBR USA 5
1400389059 en_GBR_guardi 2019-09-23 France, Germany and UK blame Iran for Saudi oilfield attack FRA DEU GBR IRN SAU 5
1517033930 en_GBR_telegr 2020-01-03 ‘Westerners should leave UAE immediately’: Gulf warning as British troops put at greater risk in Iraq after united states kills Iran military chief ARE GBR IRQ USA IRN 5
1597961952 en_GBR_telegr 2020-03-31 Britain, France and Germany bypass united states sanctions to provide Iran with medical aid GBR FRA DEU USA IRN 5
1682896357 en_GBR_telegr 2020-07-22 Australia joins united states and Japan for navy drills in the Philippine Sea as concerns grow over China AUS USA JPN PHL CHN 5
1694147850 en_GBR_telegr 2020-08-27 travel news quarantine italy greece france switzerland uk restrictions ITA GRC FRA CHE GBR 5
1707661716 en_GBR_guardi 2020-09-10 UK, France and Germany agree to reject united states demand for Iran snapback sanctions GBR FRA DEU USA IRN 5
1483750329 en_GBR_telegr 2019-02-16 Merkel says united states withdrawal from Syria will boost Russia and Iran USA SYR RUS IRN 4
1324822732 en_GBR_telegr 2019-05-15 united states rebukes British general on Iran as it orders embassy staff to leave Iraq USA GBR IRN IRQ 4
1313975713 en_GBR_guardi 2019-06-17 South Korea v Norway, Nigeria v France: Women’s World Cup clockwatch – live! KOR NOR NGA FRA 4
1315886333 en_GBR_guardi 2019-06-19 UK, France and Germany in last-ditch effort to save Iran deal GBR FRA DEU IRN 4
1381973849 en_GBR_guardi 2019-09-03 UK, united states and France may be complicit in Yemen war crimes – UN report GBR USA FRA YEM 4
1384226853 en_GBR_guardi 2019-09-05 Euro 2020: Republic of Ireland v Switzerland, Romania v Spain – live! IRL CHE ROU ESP 4
1386655906 en_GBR_guardi 2019-09-08 Euro 2020 qualifying: Sweden v Norway, Finland v Italy and more – live! SWE NOR FIN ITA 4
1419597904 en_GBR_guardi 2019-10-15 Switzerland v Republic of Ireland, Sweden v Spain: Euro 2020 – live! CHE IRL SWE ESP 4
1432711300 en_GBR_guardi 2019-10-30 Not just Russia: China and Iran may target united states elections, experts say RUS CHN IRN USA 4
1517113825 en_GBR_telegr 2019-12-27 Iran, Russia and China carry out naval drills in Indian Ocean IRN RUS CHN IND 4
1565038300 en_GBR_telegr 2019-12-29 united states carries out first strikes in a decade against Iran-backed Kataib Hizbollah in Iraq and Syria USA IRN IRQ SYR 4
1482451450 en_GBR_guardi 2019-12-30 Tehran condemns united states airstrikes in Iraq and Syria as act of terrorism IRN USA IRQ SYR 4
1510105475 en_GBR_guardi 2020-01-30 Business booms at Iran factory making united states, Israeli and British flags for burning IRN USA ISR GBR 4
1738190141 en_GBR_telegr 2020-07-26 France and Germany could join Spain on UK’s quarantine list FRA DEU ESP GBR 4
1671038069 en_GBR_telegr 2020-07-28 Chinese foreign ministry to suspend ‘mutual legal assistance’ in criminal matters between Hong Kong and the UK, Australia and Canada CHN GBR AUS CAN 4
1708910479 en_GBR_telegr 2020-08-06 UK quarantine imposed for travellers from Belgium, Andorra and the Bahamas GBR BEL AND BHS 4
1677854031 en_GBR_guardi 2020-08-07 Russia, China and Iran seeking to influence united states ahead of elections, top intelligence official says RUS CHN IRN USA 4
1683099252 en_GBR_guardi 2020-08-14 Iran and Turkey denounce UAE over deal with Israel IRN TUR ARE ISR 4
1687591712 en_GBR_guardi 2020-08-19 Australian pilots drafted to help fly UK drones over Syria and Iraq AUS GBR SYR IRQ 4
1703180856 en_GBR_telegr 2020-08-25 Switzerland to have Covid quarantine re-imposed as Czech republic, Jamaica and Iceland enter danger zone CHE CZE JAM ISL 4
1695194722 en_GBR_telegr 2020-08-28 Travel news: Switzerland, Czech Republic and Jamaica out, but Cuba in following quarantine update CHE CZE JAM CUB 4
1719242458 en_GBR_guardi 2020-09-23 UK, France and Germany summon Iranian ambassadors over prisoners GBR FRA DEU IRN 4
1766046522 en_GBR_telegr 2020-09-27 UAE, Bahrain defend ties with Israel as Palestinians cry betrayal ARE BHR ISR PSE 4
1726187015 en_GBR_telegr 2020-10-01 Travel latest news: Italy, Greece, Sweden and Poland face the chop as quarantine decision looms ITA GRC SWE POL 4
1775693184 en_GBR_telegr 2020-10-01 Turkey and Poland put on quarantine list as Greece and Italy escape TUR POL GRC ITA 4
1737834173 en_GBR_guardi 2020-10-13 Nations League: Ukraine shock Spain, Germany and Switzerland draw thriller UKR ESP DEU CHE 4
1760080346 en_GBR_guardi 2020-11-04 Coronavirus live news: England to begin lockdown as Russia, Poland, Switzerland, Austria see record case rises RUS POL CHE AUT 4
1766818486 en_GBR_guardi 2020-11-11 Netherlands v Spain, Germany v Czech Republic and more: international football – live! NLD ESP DEU CZE 4
1767020618 en_GBR_guardi 2020-11-11 International friendly roundup: Finland stun France and Belgium edge Swiss FIN FRA BEL CHE 4
1772280029 en_GBR_guardi 2020-11-17 Spain v Germany, Croatia v Portugal and more: Nations League – live! ESP DEU HRV PRT 4
1777984778 en_GBR_guardi 2020-11-23 UK, France and Germany discuss working with Joe Biden on Iran nuclear deal GBR FRA DEU IRN 4
1784491580 en_GBR_guardi 2020-12-01 France and New Zealand join Australia’s criticism of Chinese government tweet FRA NZL AUS CHN 4
1802693210 en_GBR_guardi 2020-12-20 Belgium, Italy and Netherlands ban flights from UK over new Covid strain BEL ITA NLD GBR 4

Save geographically anotated corpus

[1] "Size of resulting file =  5.721 Mo"

Thematic tags

Load tagging function

The pandemic topic

Dictionary

We decide here to use lower case transformation. We use a star for the words that can take a plural form. We had of course covid and coronavirus

code lang label
pand en pandemic*
pand en epidemic*
pand en virus
pand en world health organisation
pand en ebola
pand en h1n1
pand en sras
pand en chikungunya
pand en cholera
pand en flu
pand en covid*
pand en coronavirus
pand en sars*
pand en ncov*

Annotation

Visualization

Hypercubes creation

Aggregation function

Pandemic hypercube

[1] "Size of resulting file =  0.145 Mo"

Hypercubes exploration

Topic frequence (What ?)

Function

Example

Topic variation by media (who.what)

The function who.what explore the variation of interest for the topic in the different media of the corpus.

Function

Example

Topic variation through time (when.what)

Function

Example 1 : 2019-2020 by month

Example 2 : 2020 by week

Example 3 : Jan-March 2020 by day

Topic variation through space (where.what)

Function

Example

Spatial Networks

Geo networks modelisation

Hypercube Filter (function)

Matrix builder (function)

Random model (function)

Visualize network (function)

Application

Joining, by = "where1"
Joining, by = "where2"

Reference network

Using 'Fij' as value column. Use 'value.var' to override
Joining, by = "i"
Joining, by = "j"
`summarise()` ungrouping output (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
Joining, by = "code"
LS0tCnRpdGxlOiAiR2VvZ3JhcGhpY2FsIGFuYWx5c2lzIG9mIG1lZGlhIgpzdWJ0aXRsZTogIkFwcGxpY2F0aW9uICIKYXV0aG9yOiAiQ2xhdWRlIEdyYXNsYW5kIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShrbml0cikKCiMjIEdsb2JhbCBvcHRpb25zCm9wdGlvbnMobWF4LnByaW50PSI3NSIpCm9wdHNfY2h1bmskc2V0KGVjaG89RkFMU0UsCgkgICAgICAgICAgICAgY2FjaGU9RkFMU0UsCiAgICAgICAgICAgICAgIHByb21wdD1GQUxTRSwKICAgICAgICAgICAgICAgdGlkeT1GQUxTRSwKICAgICAgICAgICAgICAgY29tbWVudD1OQSwKICAgICAgICAgICAgICAgbWVzc2FnZT1GQUxTRSwKICAgICAgICAgICAgICAgd2FybmluZz1GQUxTRSkKCgojIEJhc2ljIHBhY2thZ2VzCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShsdWJyaWRhdGUpCgojIEdyYXBoaWMgcGFja2FnZXMKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBsb3RseSkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmxpYnJhcnkodmlzTmV0d29yaykKCiMgU3BhdGlhbCBwYWNrYWdlcwpsaWJyYXJ5KHNmKQoKIyB0ZXh0IG1pbmluZyBwYWNrYWdlcwpsaWJyYXJ5KHF1YW50ZWRhKQpsaWJyYXJ5KHF1YW50ZWRhLnRleHRwbG90cykKbGlicmFyeSh0aWR5dGV4dCkKbGlicmFyeShyZWFkdGV4dCkKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlYWRyKQpgYGAKCgoKCiMgQ29ycHVzIHByZXBhcmF0aW9uCgpXZSB1c2UgaGVyZSBkYXRhIGZyb20gTWVkaWEgY2xvdWQgd2l0aCBvbmx5IHRpdGxlIG9mIG5ld3MuIFRoZXJmb3JlIHRoZSBwcm9ncmFtIGlzIG1vcmUgc2ltcGxlIHRoYW4gaW4gY291cnNlLgoKIyMgU2VsZWN0aW9uIG9mIG1lZGlhCgoKYGBge3IgY29ycF9mciwgZXZhbD1GQUxTRX0KCiMgTG9hZCBkYXRhIHdpdGggdGhlIGZ1bmN0aW9uIGZyZWFkIChmYXN0KSBhbmQgdGhlIGVuY29kaW5nIFVURi04CmRmMTwtZnJlYWQoImRhdGEvc291cmNlL2VuX0dCUl9ndWFyZGlfMjAxOV8yMDIwLmNzdiIsIGVuY29kaW5nID0gIlVURi04IikKZGYxJG1lZGlhPC0iZW5fR0JSX2d1YXJkaSIKCgpkZjI8LWZyZWFkKCJkYXRhL3NvdXJjZS9lbl9HQlJfdGVsZWdyXzIwMTlfMjAyMC5jc3YiLCBlbmNvZGluZyA9ICJVVEYtOCIpCmRmMiRtZWRpYTwtImVuX0dCUl90ZWxlZ3IiCgoKIyB0cmFuc2Zvcm0gaW4gZGF0YS50YWJsZSBmb3JtYXQKZGY8LXJiaW5kKGRmMSxkZjIpCnJtKGRmMSxkZjIpCgoKIyBzZWxlY3QgY29sdW1uIG9mIGludGVyZXN0CmRmJGlkIDwtIGRmJHN0b3JpZXNfaWQKZGYkd2hvIDwtIGRmJG1lZGlhCmRmJHdoZW4gPC0gYXMuRGF0ZShkZiRwdWJsaXNoX2RhdGUpCmRmJHRleHQgPC0gZGYkdGl0bGUKZGY8LWRmWyxjKCJpZCIsIndobyIsIndoZW4iLCJ0ZXh0IildCmRmPC1kZltvcmRlcih3aGVuKSxdCgojIHNlbGVjdCBwZXJpb2Qgb2YgaW50ZXJlc3QKbWludGltZTwtYXMuRGF0ZSgiMjAxOS0wMS0wMSIpCm1heHRpbWU8LWFzLkRhdGUoIjIwMjAtMTItMzEiKQpkZjwtZGZbKGlzLm5hKGRmJHdoZW4pPT1GKSxdIApkZjwtZGZbYXMuRGF0ZShkZiR3aGVuKSA+PSBtaW50aW1lLF0KZGY8LWRmW2FzLkRhdGUoZGYkd2hlbikgPD0gbWF4dGltZSxdCgojIGVsaW1pbmF0ZSBkdXBsaWNhdGUKZGY8LWRmW2R1cGxpY2F0ZWQoZGYkdGV4dCk9PUYsXQoKCgpgYGAKCgojIyBDaGVjayBvZiB0aW1lIGZyZXF1ZW5jeQoKCiMjIyBUaW1lIGRpdmlzaW9ucwoKV2UgdHJhbnNmb3JtIHRoZSBwcmV2aW91cyBkYXRhLmZyYW1lIGluIGEgZGF0YS50YWJsZSBmb3JtYXQgZm9yIGVhc2llciBvcGVyYXRpb25zIG9mIGFnZ3JlZ2F0aW9uIAoKYGBge3IgdGltZSBkaXYsIGV2YWwgPSBGQUxTRX0KZHQ8LWFzLmRhdGEudGFibGUoZGYpCmR0JGRheSAgICAgPC0gYXMuRGF0ZShkdCR3aGVuKQpkdCR3ZWVrICAgIDwtIGN1dChkdCRkYXksICJ3ZWVrcyIsIHN0YXJ0Lm9uLm1vbmRheT1UUlVFKQpkdCRtb250aCAgIDwtIGN1dChkdCRkYXksICJtb250aHMiKQpkdCR3ZWVrZGF5IDwtIHdlZWtkYXlzKGR0JGRheSkKCiMgU2F2ZSBkYXRhIGZyYW1lCnNhdmVSRFMoZHQsImRhdGEvY29ycHVzL2R0X215Y29ycHVzLlJEUyIpIApgYGAKCgojIyMgTmV3cyBieSB3ZWVrCgoKCgpXZSBleGFtaW5lIGlmIHRoZSBkaXN0cmlidXRpb24gaXMgcmVndWxhciBieSB3ZWVrIGZvciB0aGUgZGlmZmVyZW50IG1lZGlhIG9mIHRoZSBjb3JwdXMuCgpgYGB7ciBuZXdzX3dlZWtfZnJ9CmR0PC1yZWFkUkRTKCJkYXRhL2NvcnB1cy9kdF9teWNvcnB1cy5SRFMiKQpuZXdzX3dlZWtzPC1kdFssLihuZXdzdG90PS5OKSxieT0uKHdlZWssd2hvKV0KCnA8LWdncGxvdChuZXdzX3dlZWtzLCBhZXMoeD1hcy5EYXRlKHdlZWspLHk9bmV3c3RvdCwgY29sPXdobykpKwogICBnZW9tX2xpbmUoKSsKICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gJ2xvZXNzJywgZm9ybXVsYSA9ICd5fngnKSsKICAgc2NhbGVfeV9jb250aW51b3VzKCJOdW1iZXIgb2YgbmV3cyIsIGxpbWl0cyA9IGMoMCxOQSkpICsKICAgc2NhbGVfeF9kYXRlKCJXZWVrIChzdGFydGluZyBvbiBtb25kYXkpIikgKwogICAgICAgICBnZ3RpdGxlKGxhYmVsID0iQ29ycHVzIDogZGlzdHJpYnV0aW9uIG9mIG5ld3MgYnkgd2VlayIpCnAKYGBgCgojIyMgTmV3cyBieSB3ZWVrZGF5CgpXZSBleGFtaW5lIGlmIHRoZSBkaXN0cmlidXRpb24gaXMgcmVndWxhciBieSB3ZWVrZGF5IGFuZCBjaGVjayBpbiBwYXJ0aWN1bGFyIHRoZSBlZmZlY3Qgb2YgdGhlIHdlZWstZW5kLgoKYGBge3IgbmV3c193ZWVrZGF5c19mcn0KI2NvbXB1dGUgZnJlcXVlbmNpZXMgYnkgd2Vla2RheQpuZXdzX3dlZWtkYXlzPC1kdFssLihuZXdzdG90PS5OKSxieT0uKHdlZWtkYXksd2hvKV0KbmV3c193ZWVrZGF5czwtbmV3c193ZWVrZGF5c1ssLih3ZWVrZGF5LG5ld3NwY3Q9MTAwKm5ld3N0b3Qvc3VtKG5ld3N0b3QpKSxieT0uKHdobyldCgoKIyBUcmFuc2xhdGUgd2Vla2RheXMgaW4gZW5nbGlzaCBhbmQgb3JkZXIKbmV3c193ZWVrZGF5cyR3ZWVrZGF5PC1hcy5mYWN0b3IobmV3c193ZWVrZGF5cyR3ZWVrZGF5KQpsZXZlbHMobmV3c193ZWVrZGF5cyR3ZWVrZGF5KTwtYygiNy5TdW5kYXkiLCI0LldlZG5lc2RheSIsIjEuTW9uZGF5IiwiMi5UdWVzZGF5IiwiMy5UaHVyc2RheSIsIjYuU2F0aHVyZGF5IiwiNS5GcmlkYXkiKQpuZXdzX3dlZWtkYXlzJHdlZWtkYXk8LWFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIobmV3c193ZWVrZGF5cyR3ZWVrZGF5KSkKbmV3c193ZWVrZGF5czwtbmV3c193ZWVrZGF5c1tvcmRlcihuZXdzX3dlZWtkYXlzJHdlZWtkYXkpLF0KCgpwPC1nZ3Bsb3QobmV3c193ZWVrZGF5cywgYWVzKHg9d2Vla2RheSxmaWxsID0gd2hvLCB5PW5ld3NwY3QpKSsKICAgICAgICAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZG9kZ2UiLCBzdGF0PSJpZGVudGl0eSIpKwogICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoIlNoYXJlIG9mIG5ld3MgKCUpIiwgbGltaXRzID0gYygwLE5BKSkgKwogICAgICAgICBnZ3RpdGxlKGxhYmVsID0iQ29ycHVzIDogZGlzdHJpYnV0aW9uIG9mIG5ld3MgYnkgd2VlayBkYXkiKQpwCmBgYAoKCiMjIFRyYW5zZm9ybSBpbiBxdWFudGVkYSBjb3JwdXMKCgoKYGBge3Igc2VudF9mcn0KCiMgdHJhbnNmb3JtIGluIHF1YW50ZWRhCnFkPC1jb3JwdXMoZHQsZG9jaWRfZmllbGQgPSAiaWQiLHRleHRfZmllbGQgPSAidGV4dCIpCgoKIyBmaWx0ZXIgYnkgbnVtYmVyIG9mIHRva2VucyBieSBzZW50ZW5jZQpxZCRuYnQ8LW50b2tlbih0ZXh0cyhxZCkpCnFkPC1jb3JwdXNfc3Vic2V0KHFkLCBuYnQ8MTAwKQpxZDwtY29ycHVzX3N1YnNldChxZCwgbmJ0PjIpCgoKCiMgU2F2ZSBjb3JwdXMgaW4gcWQgZm9ybWF0CnNhdmVSRFMocWQsImRhdGEvY29ycHVzL3FkX215Y29ycHVzLlJEUyIpCgoKCmhlYWQocWQpCnN1bW1hcnkocWQsMykKYGBgCgoKCgoKIyBHZW9ncmFwaGljYWwgdGFncwoKCiMjIFByZXBhcmF0aW9uIG9mIGRhdGEKCgojIyMgTG9hZCBkaWN0b25hcnkKCldlIHN0YXJ0IGJ5IGxvYWRpbmcgdGhlIGxhc3QgdmVyc2lvbiBvZiB0aGUgSW1hZ2V1biBkaWN0aW9uYXJ5IGFuZCB3ZSBleHRyYWN0IG91ciB0YXJnZXQgbGFuZ3VhZ2UgKGhlcmUgOiBlbmdsaXNoKS4KCmBgYHtyIGxvYWRfZGljdH0KIyBMb2FkIG11bHRpbGFuZ3VhZ2UgZGljdGlvbmFyeQpkaWN0PC1mcmVhZCgiZGF0YS9kaWNvX3N0YXRlcy9nbG9iYWxfc3RhdGVfVjIuY3N2IikKCiMgU2VsZWN0IGZyZW5jaCBkaWN0aW9uYXJ5CmRpY3QgPC0gZGljdFtkaWN0JGxhbmc9PSJlbiIsXQoKCmhlYWQoZGljdCkKYGBgCgojIyMgTG9hZCBjb3JwdXMKCmBgYHtyfQpxZCA8LSByZWFkUkRTKCJkYXRhL2NvcnB1cy9xZF9teWNvcnB1cy5SRFMiKQoKCmBgYAoKIyMjIExvYWQgdGFnZ2luZyBmdW5jdGlvbgoKYGBge3IgZnVuY19hbm5vdGF0ZX0KZXh0cmFjdF90YWdzIDwtIGZ1bmN0aW9uKHFkID0gcWQsICAgICAgICAgICAgICAgICAgICAgICMgdGhlIGNvcnB1cyBvZiBpbnRlcmVzdAogICAgICAgICAgICAgICAgICAgICAgICAgbGFuZyA9ICJmciIsICAgICAgICAgICAgICAgICAgIyB0aGUgbGFuZ3VhZ2UgdG8gYmUgdXNlZAogICAgICAgICAgICAgICAgICAgICAgICAgZGljdCA9IGRpY3QsICAgICAgICAgICAgICAgICAgIyB0aGUgZGljdGlvbmFyeSBvZiB0YXJnZXQgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2RlID0gIklTTzMiICwgICAgICAgICAgICAgICAgIyB2YXJpYWJsZSB1c2VkIGZvciBjb2RpbmcKICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWFzID0gIngiLCAgICAgICAgICAgICAgICAgICAjIHZhcmlhYmxlIHVzZWQgZm9yIGFsaWFzCiAgICAgICAgICAgICAgICAgICAgICAgICB0YWdzbmFtZSA9ICJzdGF0ZXMiLCAgICAgICAgICAgIyBuYW1lIG9mIHRoZSB0YWdzIGNvbHVtbgogICAgICAgICAgICAgICAgICAgICAgICAgc3BsaXQgID0gYygiJyIsIuKAmSIsIi0iKSwgICAgICAgIyBzcGxpdCBsaXN0CiAgICAgICAgICAgICAgICAgICAgICAgICB0b2xvdyA9IFRSVUUgICwgICAgICAgICAgICAgICAgIyBUb2tlbml6ZSB0ZXh0CiAgICAgICAgICAgICAgICAgICAgICAgICBjb21wcyA9IGMoIkFmcmlxdWUgZHUgc3VkIikgICMgY29tcG91bmRzCiAgICAgICAgICAgICAgICAgICAgICAgICApCnsgCgoKICAKIyBUb2tlbml6ZSAgCng8LWFzLmNoYXJhY3RlcihxZCkKCgppZihsZW5ndGgoc3BsaXQpID4gMCkgeyByZWc8LXBhc3RlKHNwbGl0LCBjb2xsYXBzZSA9ICd8JykKICAgICAgICAgICAgICAgICAgICAgICB4IDwtIGdzdWIocmVnLCIgIix4KX0gIAppZih0b2xvdykgeyB4IDwtIHRvbG93ZXIoeCl9IAp0b2tzPC10b2tlbnMoeCkKCiMgY29tcG91bmRzCmlmKGxlbmd0aChzcGxpdCkgPiAwKSB7IHJlZzwtcGFzdGUoc3BsaXQsIGNvbGxhcHNlID0gJ3wnKQogICAgICAgICAgICAgICAgICAgICAgIGNvbXBzPC0gZ3N1YihyZWcsIiAiLGNvbXBzKX0gIAppZih0b2xvdykgICAgICAge2NvbXBzIDwtIHRvbG93ZXIoY29tcHMpfSAgCnRva3M8LXRva2Vuc19jb21wb3VuZCh0b2tzLHBhdHRlcm49cGhyYXNlKGNvbXBzKSkKCiAgCiMgTG9hZCBkaWN0aW9uYXJpZXMgYW5kIGNyZWF0ZSBjb21wb3VuZHMKCiAgIyMgVGFyZ2V0IGRpY3Rpb25hcnkKCmxhYmVscyA8LWRpY3RbW2FsaWFzXV0KaWYobGVuZ3RoKHNwbGl0KSA+IDApIHsgcmVnPC1wYXN0ZShzcGxpdCwgY29sbGFwc2UgPSAnfCcpCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPC0gZ3N1YihyZWcsIiAiLGxhYmVscyl9ICAKaWYodG9sb3cpICAgICAgIHtsYWJlbHMgPC0gdG9sb3dlcihsYWJlbHMpfSAgCnRva3M8LXRva2Vuc19jb21wb3VuZCh0b2tzLHBhdHRlcm49cGhyYXNlKGxhYmVscykpCiAgCiAjIGNyZWF0ZSBxdWFudGVkYSBkaWN0aW9uYXJ5CmtleXMgPC1nc3ViKCIgIiwiXyIsbGFiZWxzKQpxZF9kaWN0PC1hcy5saXN0KGtleXMpCm5hbWVzKHFkX2RpY3QpPC1kaWN0W1tjb2RlXV0KcWRfZGljdDwtZGljdGlvbmFyeShxZF9kaWN0LHRvbG93ZXIgPSBGQUxTRSkKCiMgSWRlbnRpZnkgZ2VvIHRhZ3MgKHN0YXRlcyBvciByZWcgb3Igb3JnIC4uLikKdG9rc190YWdzIDwtIHRva2Vuc19sb29rdXAodG9rcywgcWRfZGljdCwgY2FzZV9pbnNlbnNpdGl2ZSA9IEYpCnRva3NfdGFncyA8LSBsYXBwbHkodG9rc190YWdzLCB1bmlxdWUpCnRva3NfdGFnczwtYXMudG9rZW5zKHRva3NfdGFncykKbGlzdF90YWdzPC1mdW5jdGlvbih4KXtyZXM8LXBhc3RlKHgsIGNvbGxhcHNlPScgJyl9CmRvY3ZhcnMocWQpW1t0YWdzbmFtZV1dPC1hcy5jaGFyYWN0ZXIobGFwcGx5KHRva3NfdGFncyxGVU49bGlzdF90YWdzKSkKZG9jdmFycyhxZClbW3Bhc3RlKCJuYiIsdGFnc25hbWUsc2VwPSIiKV1dPC1udG9rZW4odG9rc190YWdzKQoKCgojIEV4cG9ydCByZXN1bHRzCnJldHVybihxZCkKIH0KYGBgCgoKCiMjIEdlb2dyYXBoaWNhbCBhbm5vdGF0aW9uCgojIyMgQW5ub3RhdGUgYWxsIGVudGl0aWVzCgoKYGBge3IgYW5ub3RhdGUsIGV2YWw9RkFMU0V9CiMgc21hbGwgY29ycmVjdGlvbgp0ZXh0czwtZ3N1YigiIFVTIiwiIFVuaXRlZCBTdGF0ZXMiLCBxZCkKdGV4dHM8LWdzdWIoIlVTICIsIlVuaXRlZCBTdGF0ZXMgIiwgdGV4dHMpCnFkPC1jb3JwdXModGV4dHMsZG9jdmFycyA9IGRvY3ZhcnMocWQpKQoKCnQxPC1TeXMudGltZSgpCgpmcmNvbXBzPC1jKCJDaGluYSBzZWEiLCAiaW5kaWFuIG9jZWFuIiwgImFtZXJpY2FuIGNvbnRpbmVudCIsICJhbWVyaWNhbiBjb3VudHJpZXMiKQoKcWQgPC0gZXh0cmFjdF90YWdzIChxZCA9IHFkLAogICAgICAgICAgICAgICAgICAgICBsYW5nPSJlbiIsCiAgICAgICAgICAgICAgICAgICAgIGRpY3QgPSBkaWN0LAogICAgICAgICAgICAgICAgICAgICBjb2RlID0gIklTTzMiLAogICAgICAgICAgICAgICAgICAgICBhbGlhcyA9ICJ4IiwKICAgICAgICAgICAgICAgICAgICAgdGFnc25hbWUgPSAic3RhdGVzIiwKICAgICAgICAgICAgICAgICAgICAgc3BsaXQgPSBjKCInIiwi4oCZIiwiLSIpLAogICAgICAgICAgICAgICAgICAgICBjb21wcyA9IGZyY29tcHMsCiAgICAgICAgICAgICAgICAgICAgIHRvbG93ID0gVFJVRSkKCnQyID0gU3lzLnRpbWUoKQpwYXN0ZSgiUHJvZ3JhbSBleGVjdXRlZCBpbiAiLCB0Mi10MSkKCnRhYmxlKHFkJG5ic3RhdGVzKQoKCmBgYAoKCgojIyMgY2hlY2sgbmV3cyB3aXRoIG1heGltdW0gc3RhdGUgbnVtYmVyCgpgYGB7ciBjaGVja19zdGF0ZXNfbmV3c30KdGFibGUocWQkbmJzdGF0ZXMpCmNoZWNrPC1jb3JwdXNfc3Vic2V0KHFkLG5ic3RhdGVzPjMpCng8LWRhdGEuZnJhbWUod2hvPWNoZWNrJHdobyx3aGVuID0gY2hlY2skd2hlbix0ZXh0PWFzLmNoYXJhY3RlcihjaGVjayksc3RhdGVzPWNoZWNrJHN0YXRlcyxuYnN0YXRlcz1jaGVjayRuYnN0YXRlcykKeDwteFtvcmRlcih4JG5ic3RhdGVzLGRlY3JlYXNpbmcgPSBUKSxdCmthYmxlKHgpCmBgYAoKCgoKCgoKIyMjIFNhdmUgZ2VvZ3JhcGhpY2FsbHkgYW5vdGF0ZWQgY29ycHVzCgpgYGB7cn0Kc2F2ZVJEUyhxZCwiZGF0YS9jb3JwdXMvcWRfbXljb3JwdXNfc3RhdGVzLlJEUyIpCnBhc3RlKCJTaXplIG9mIHJlc3VsdGluZyBmaWxlID0gIixyb3VuZChmaWxlLnNpemUoImRhdGEvY29ycHVzL3FkX215Y29ycHVzX3N0YXRlcy5SRFMiKS8xMDAwMDAwLDMpLCAiTW8iKQpgYGAKCgoKCiMgVGhlbWF0aWMgdGFncwoKCgpgYGB7cn0KcWQgPC1yZWFkUkRTKCJkYXRhL2NvcnB1cy9xZF9teWNvcnB1c19zdGF0ZXMuUkRTIikKYGBgCgoKCiMjIExvYWQgdGFnZ2luZyBmdW5jdGlvbgoKCmBgYHtyIGZ1bmNfYW5ub3RhdGUyfQpleHRyYWN0X3RhZ3MgPC0gZnVuY3Rpb24ocWQgPSBxZCwgICAgICAgICAgICAgICAgICAgICAgIyB0aGUgY29ycHVzIG9mIGludGVyZXN0CiAgICAgICAgICAgICAgICAgICAgICAgICBsYW5nID0gImZyIiwgICAgICAgICAgICAgICAgICAjIHRoZSBsYW5ndWFnZSB0byBiZSB1c2VkCiAgICAgICAgICAgICAgICAgICAgICAgICBkaWN0ID0gZGljdCwgICAgICAgICAgICAgICAgICAjIHRoZSBkaWN0aW9uYXJ5IG9mIHRhcmdldCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUgPSAiY29kZSIgLCAgICAgICAgICAgICAgICAjIHZhcmlhYmxlIHVzZWQgZm9yIGNvZGluZwogICAgICAgICAgICAgICAgICAgICAgICAgYWxpYXMgPSAiYWxpYXMiLCAgICAgICAgICAgICAgICMgdmFyaWFibGUgdXNlZCBmb3IgYWxpYXMKICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3NuYW1lID0gInN0YXRlcyIsICAgICAgICAgICAjIG5hbWUgb2YgdGhlIHRhZ3MgY29sdW1uCiAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdCAgPSBjKCInIiwi4oCZIiwiLSIpLCAgICAgICAjIHNwbGl0IGxpc3QKICAgICAgICAgICAgICAgICAgICAgICAgIHRvbG93ID0gVFJVRSAgLCAgICAgICAgICAgICAgICAjIFRva2VuaXplIHRleHQKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBzID0gYygiQWZyaXF1ZSBkdSBzdWQiKSAgIyBjb21wb3VuZHMKICAgICAgICAgICAgICAgICAgICAgICAgICkKeyAKCgogIAojIFRva2VuaXplICAKeDwtYXMuY2hhcmFjdGVyKHFkKQoKCmlmKGxlbmd0aChzcGxpdCkgPiAwKSB7IHJlZzwtcGFzdGUoc3BsaXQsIGNvbGxhcHNlID0gJ3wnKQogICAgICAgICAgICAgICAgICAgICAgIHggPC0gZ3N1YihyZWcsIiAiLHgpfSAgCmlmKHRvbG93KSB7IHggPC0gdG9sb3dlcih4KX0gCnRva3M8LXRva2Vucyh4KQoKIyBjb21wb3VuZHMKaWYobGVuZ3RoKHNwbGl0KSA+IDApIHsgcmVnPC1wYXN0ZShzcGxpdCwgY29sbGFwc2UgPSAnfCcpCiAgICAgICAgICAgICAgICAgICAgICAgY29tcHM8LSBnc3ViKHJlZywiICIsY29tcHMpfSAgCmlmKHRvbG93KSAgICAgICB7Y29tcHMgPC0gdG9sb3dlcihjb21wcyl9ICAKdG9rczwtdG9rZW5zX2NvbXBvdW5kKHRva3MscGF0dGVybj1waHJhc2UoY29tcHMpKQoKICAKIyBMb2FkIGRpY3Rpb25hcmllcyBhbmQgY3JlYXRlIGNvbXBvdW5kcwoKICAjIyBUYXJnZXQgZGljdGlvbmFyeQoKbGFiZWxzIDwtZGljdFtbYWxpYXNdXQppZihsZW5ndGgoc3BsaXQpID4gMCkgeyByZWc8LXBhc3RlKHNwbGl0LCBjb2xsYXBzZSA9ICd8JykKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM8LSBnc3ViKHJlZywiICIsbGFiZWxzKX0gIAppZih0b2xvdykgICAgICAge2xhYmVscyA8LSB0b2xvd2VyKGxhYmVscyl9ICAKdG9rczwtdG9rZW5zX2NvbXBvdW5kKHRva3MscGF0dGVybj1waHJhc2UobGFiZWxzKSkKICAKICMgY3JlYXRlIHF1YW50ZWRhIGRpY3Rpb25hcnkKa2V5cyA8LWdzdWIoIiAiLCJfIixsYWJlbHMpCnFkX2RpY3Q8LWFzLmxpc3Qoa2V5cykKbmFtZXMocWRfZGljdCk8LWRpY3RbW2NvZGVdXQpxZF9kaWN0PC1kaWN0aW9uYXJ5KHFkX2RpY3QsdG9sb3dlciA9IEZBTFNFKQoKIyBJZGVudGlmeSBnZW8gdGFncyAoc3RhdGVzIG9yIHJlZyBvciBvcmcgLi4uKQp0b2tzX3RhZ3MgPC0gdG9rZW5zX2xvb2t1cCh0b2tzLCBxZF9kaWN0LCBjYXNlX2luc2Vuc2l0aXZlID0gRikKdG9rc190YWdzIDwtIGxhcHBseSh0b2tzX3RhZ3MsIHVuaXF1ZSkKdG9rc190YWdzPC1hcy50b2tlbnModG9rc190YWdzKQpsaXN0X3RhZ3M8LWZ1bmN0aW9uKHgpe3JlczwtcGFzdGUoeCwgY29sbGFwc2U9JyAnKX0KZG9jdmFycyhxZClbW3RhZ3NuYW1lXV08LWFzLmNoYXJhY3RlcihsYXBwbHkodG9rc190YWdzLEZVTj1saXN0X3RhZ3MpKQpkb2N2YXJzKHFkKVtbcGFzdGUoIm5iIix0YWdzbmFtZSxzZXA9IiIpXV08LW50b2tlbih0b2tzX3RhZ3MpCgoKCiMgRXhwb3J0IHJlc3VsdHMKcmV0dXJuKHFkKQogfQpgYGAKCgojIyBUaGUgcGFuZGVtaWMgdG9waWMKCiMjIyBEaWN0aW9uYXJ5CgpXZSBkZWNpZGUgaGVyZSB0byB1c2UgbG93ZXIgY2FzZSB0cmFuc2Zvcm1hdGlvbi4gV2UgdXNlIGEgc3RhciBmb3IgdGhlIHdvcmRzIHRoYXQgY2FuIHRha2UgYSBwbHVyYWwgZm9ybS4gV2UgaGFkIG9mIGNvdXJzZSBjb3ZpZCBhbmQgY29yb25hdmlydXMgCgpgYGB7ciBkaWNvIHBhbmRlbWljfQpsYWJlbCA8LSBjKCJwYW5kZW1pYyoiLCAiZXBpZGVtaWMqIiwgInZpcnVzIiwgIndvcmxkIGhlYWx0aCBvcmdhbmlzYXRpb24iLCAiZWJvbGEiLCAgImgxbjEiLCJzcmFzIiwgImNoaWt1bmd1bnlhIiwgImNob2xlcmEiLCAiZmx1IiwgImNvdmlkKiIsImNvcm9uYXZpcnVzIiwgInNhcnMqIiwibmNvdioiKQpjb2RlICA8LSByZXAoInBhbmQiLCBsZW5ndGgobGFiZWwpKQpsYW5nICA8LSByZXAoImVuIiwgbGVuZ3RoKGxhYmVsKSkKZGljdF9wYW5kZSA8LSBkYXRhLmZyYW1lKGNvZGUsbGFuZyxsYWJlbCkKa2FibGUoZGljdF9wYW5kZSkKCmVuY29tcHM8LWMoImNvbXB1dGVyIHZpcnVzIikKYGBgCgoKIyMjIEFubm90YXRpb24KCmBgYHtyIGFubm90YXRlIHBhbmRlbWljLCBldmFsPUZBTFNFfQoKcWQgPC0gZXh0cmFjdF90YWdzIChxZCA9IHFkLAogICAgICAgICAgICAgICAgICAgICBsYW5nPSJlbiIsCiAgICAgICAgICAgICAgICAgICAgIGRpY3QgPSBkaWN0X3BhbmRlLAogICAgICAgICAgICAgICAgICAgICBjb2RlID0gImNvZGUiLAogICAgICAgICAgICAgICAgICAgICBhbGlhcyA9ICJsYWJlbCIsCiAgICAgICAgICAgICAgICAgICAgdGFnc25hbWUgPSAicGFuZCIsCiAgICAgICAgICAgICAgICAgICAgIHNwbGl0ID0gYygiJyIsIuKAmSIsIi0iKSwKICAgICAgICAgICAgICAgICAgICAgY29tcHMgPSBlbmNvbXBzLAogICAgICAgICAgICAgICAgICAgICB0b2xvdyA9IFRSVUUpCgp0YWJsZShxZCRuYnBhbmQpCgpzYXZlUkRTKHFkLCJkYXRhL2NvcnB1cy9xZF9teWNvcnB1c19zdGF0ZXNfdG9waWMuUkRTIikKCmBgYAoKCiMjIyBWaXN1YWxpemF0aW9uCgoKYGBge3IgdmlzdWFsaXphdGlvbiBwYW5kZW1pY30KeDwtZGF0YS50YWJsZShkb2N2YXJzKHFkKSkKeCR0YWc8LXgkbmJwYW5kICE9MAp0YWI8LXhbLC4odG90PS5OKSxieT0uKG1vbnRoLHRhZywgd2hvKV0KdGFiPC10YWJbdGFiJHRhZz09VFJVRSxdCnRhYiRtb250aDwtYXMuRGF0ZSh0YWIkbW9udGgpCgogICAgICAgCiAgICAgICBwPC1nZ3Bsb3QodGFiLCBhZXMoeD1tb250aCxmaWxsID13aG8sIHk9dG90KSkrCiAgICAgICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikrCiAgICAgICAgIGdndGl0bGUobGFiZWwgPSJQYW5kZW1pYyA6IGRpc3RyaWJ1dGlvbiBvZiB0YWdzIGJ5IG1vbnRoIGFuZCBtZWRpYSIpCnAKYGBgCgoKCgojIEh5cGVyY3ViZXMgY3JlYXRpb24KCgoKIyMgQWdncmVnYXRpb24gZnVuY3Rpb24KCgpgYGB7cn0KCiMnIEB0aXRsZSBjcmVhdGUgYW4gaHlwZXJjdWJlCiMnIEBuYW1lIGh5cGVyY3ViZQojJyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgbmV0d29yayBvZiBpbnRlcmxpbmtlZCBzdGF0ZXMKIycgQHBhcmFtIGNvcnB1cyBhIGNvcnB1cyBvZiBuZXdzIGluIHF1YW50ZWRhIGZvcm1hdAojJyBAcGFyYW0gb3JkZXIgYW4gb3JkZXIgb2Ygc2VudGVuY2VzIGluIHRoZSBuZXdzCiMnIEBwYXJhbSB3aG8gdGhlIHNvdXJjZSBkaW1lbnNpb24KIycgQHBhcmFtIHdoZW4gdGhlIHRpbWUgZGltZW5zaW9uCiMnIEBwYXJhbSB0aW1lc3BhbiBhZ2dyZWF0aW9uIG9mIHRpbWUKIycgQHBhcmFtIHdoYXQgYSBsaXN0IG9mIHRvcGljcwojJyBAcGFyYW0gd2hlcmUxIGEgbGlzdCBvZiBzdGF0ZXMKIycgQHBhcmFtIHdoZXJlMiAgYSBsaXN0IG9mIHN0YXRlcwoKCmh5cGVyY3ViZSAgIDwtIGZ1bmN0aW9uKCBjb3JwdXMgPSBxZCwKICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSAib3JkZXIiLAogICAgICAgICAgICAgICAgICAgICAgICB3aG8gPSAic291cmNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiA9ICJ3aGVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgdGltZXNwYW4gPSAid2VlayIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdoYXQgPSAid2hhdCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlMSA9ICJ3aGVyZTEiLAogICAgICAgICAgICAgICAgICAgICAgICB3aGVyZTIgPSAid2hlcmUyIikKewoKCiAgCiMgcHJlcGFyZSBkYXRhCgogIGRvbjwtZG9jdmFycyhjb3JwdXMpCiAgCiAgZGY8LWRhdGEudGFibGUoaWQgICAgID0gZG9jaWQoY29ycHVzKSwKICAgICAgICAgICAgICAgICBvcmRlciAgPSBkb25bW29yZGVyXV0sCiAgICAgICAgICAgICAgICAgd2hvICAgID0gZG9uW1t3aG9dXSwKICAgICAgICAgICAgICAgICB3aGVuICAgPSBkb25bW3doZW5dXSwKICAgICAgICAgICAgICAgICB3aGF0ICAgPSBkb25bW3doYXRdXSwKICAgICAgICAgICAgICAgICB3aGVyZTEgPSBkb25bW3doZXJlMV1dLAogICAgICAgICAgICAgICAgIHdoZXJlMiA9IGRvbltbd2hlcmUyXV0pCgogICMgYWRqdXN0IGlkCiBkZiRpZDwtcGFzdGUoZGYkaWQsIl8iLGRmJG9yZGVyLHNlcD0iIikKIAojIGNoYW5nZSB0aW1lIHNwYW4KICBkZiR3aGVuPC1hcy5jaGFyYWN0ZXIoY3V0KGFzLkRhdGUoZGYkd2hlbiksIHRpbWVzcGFuLCBzdGFydC5vbi5tb25kYXkgPSBUUlVFKSkKCiMgdW5uZXN0IHdoZXJlMQogIGRmJHdoZXJlMVtkZiR3aGVyZTE9PSIiXTwtIl9ub18iCiAgZGY8LXVubmVzdF90b2tlbnMoZGYsd2hlcmUxLHdoZXJlMSx0b19sb3dlcj1GKQogIAojIHVubmVzdCB3aGVyZTIKICBkZiR3aGVyZTJbZGYkd2hlcmUyPT0iIl08LSJfbm9fIgogIGRmPC11bm5lc3RfdG9rZW5zKGRmLHdoZXJlMix3aGVyZTIsdG9fbG93ZXI9RikgCiAgCiMgdW5uZXN0IHdoYXQKICBkZiR3aGF0W2RmJHdoYXQ9PSIiXTwtIl9ub18iCiAgZGY8LXVubmVzdF90b2tlbnMoZGYsd2hhdCx3aGF0LHRvX2xvd2VyPUYpIAogIAoKCiMgQ29tcHV0ZSB3ZWlnaHQgb2YgbmV3cwogIG5ld3N3Z3Q8LWRmWyxsaXN0KHdndD0xLy5OKSxsaXN0KGlkKV0KICBkZiA8LSBtZXJnZShkZixuZXdzd2d0LCBieT0iaWQiKQoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEh5cGVyY3ViZSBjcmVhdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLSMKICAKICAKIyBBZ2dyZWdhdGUKICBoYzwtIGRmWywuKHRhZ3MgPSAuTiwgbmV3cz1zdW0od2d0KSkgLC4ob3JkZXIsd2hvLCB3aGVuLHdoZXJlMSx3aGVyZTIsIHdoYXQpXQogIAojIENvbnZlcnQgZGF0ZSB0byB0aW1lCiAgaGMkd2hlbjwtYXMuRGF0ZShoYyR3aGVuKQogIAojIGV4cG9ydAogIHJldHVybihoYykKICAKfQoKYGBgCgoKIyMgUGFuZGVtaWMgaHlwZXJjdWJlCgpgYGB7cn0KcWQ8LXJlYWRSRFMoImRhdGEvY29ycHVzL3FkX215Y29ycHVzX3N0YXRlc190b3BpYy5SRFMiKQpxZCRvcmRlcjwtMQoKaGM8LWh5cGVyY3ViZSggY29ycHVzICAgPSBxZCwKICAgICAgICAgICAgICAgICAgICBvcmRlciAgICA9ICJvcmRlciIsCiAgICAgICAgICAgICAgICAgICAgd2hvICAgICAgPSAid2hvIiwKICAgICAgICAgICAgICAgICAgICB3aGVuICAgICA9ICJ3aGVuIiwKICAgICAgICAgICAgICAgICAgICB0aW1lc3BhbiA9ICJkYXkiLAogICAgICAgICAgICAgICAgICAgIHdoYXQgICAgID0gInBhbmQiLAogICAgICAgICAgICAgICAgICAgIHdoZXJlMSAgID0gInN0YXRlcyIsCiAgICAgICAgICAgICAgICAgICAgd2hlcmUyICAgPSAic3RhdGVzIikKCnNhdmVSRFMoaGMsImRhdGEvY29ycHVzL2hjX215Y29ycHVzX3N0YXRlc19wYW5kLlJEUyIpCnBhc3RlKCJTaXplIG9mIHJlc3VsdGluZyBmaWxlID0gIixyb3VuZChmaWxlLnNpemUoImRhdGEvY29ycHVzL2hjX215Y29ycHVzX3N0YXRlc19wYW5kLlJEUyIpLzEwMDAwMDAsMyksICJNbyIpCmBgYAoKCgoKCiMgSHlwZXJjdWJlcyBleHBsb3JhdGlvbgoKCgoKCmBgYHtyfQojIyMjIC0tLS0tLS0tLS0tLS0tLS0gdGVzdGNoaTIgLS0tLS0tLS0tLS0tLS0tLQojJyBAdGl0bGUgIENvbXB1dGUgdGhlIGF2ZXJhZ2Ugc2FsaWVuY2Ugb2YgdGhlIHRvcGljIGFuZCB0ZXN0IHNpZ25pZmljYW5jZSBvZiBkZXZpYXRpb24KIycgQG5hbWUgd2hhdAojJyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGFibGUgYW5kIGdyYXBoaWMgb2YgdGhlIHRvcGljCiMnIEBwYXJhbSB0YWJ0ZXN0IGEgdGFibGUgd2l0aCB2YXJpYWJsZSB0cmlhbCwgc3VjY2VzcyBhbmQgbnVsbC52YWx1ZQojJyBAcGFyYW0gbWluc2FtcCA6IFRocmVzaG9sZCBvZiBzYW1wbGUgc2l6ZSByZXF1ZXN0ZWQgZm9yIHNhbGllbmNlIGNvbXB1dGF0aW9uCiMnIEBwYXJhbSBtaW50ZXN0IDogVGhyZXNob2xkIG9mIGVzdGltYXRlZCB2YWx1ZSByZXF1ZXN0ZWQgZm9yIGNoaS1zcXVhcmUgdGVzdAoKCnRlc3RjaGkyPC1mdW5jdGlvbih0YWJ0ZXN0PXRhYnRlc3QsCiAgICAgICAgICAgICAgICAgICBtaW5zYW1wID0gMjAsCiAgICAgICAgICAgICAgICAgICBtaW50ZXN0ID0gNSkgCnsKICB0YWI8LXRhYnRlc3QKICBuPC1kaW0odGFiKVsxXQogIAogICMgQ29tcHV0ZSBzYWxpZW5jZSBpZiBzYW1wbGUgc2l6ZSBzdWZmaWNpZW50IChkZWZhdWx0IDogTj4yMCkKICB0YWIkZXN0aW1hdGUgPC1OQQogIHRhYiRzYWxpZW5jZSA8LU5BCiAgdGFiJGNoaTI8LU5BCiAgdGFiJHAudmFsdWU8LU5BCiAgaWYgKHRhYiR0cmlhbCA+IG1pbnNhbXApeyB0YWIkZXN0aW1hdGU8LXJvdW5kKHRhYiRzdWNjZXNzL3RhYiR0cmlhbCw1KQogIHRhYiRzYWxpZW5jZTwtdGFiJGVzdGltYXRlL3RhYiRudWxsLnZhbHVlCiAgCiAgIyBDaGktc3F1YXJlIHRlc3QgaWYgZXN0aW1hdGVkIHZhbHVlIHN1ZmZpY2llbnQgKGRlZmF1bHQgOiBOaWoqID4gNSkKICAKICBmb3IgKGkgaW4gMTpuKSB7CiAgICBpZih0YWIkdHJpYWxbaV0qdGFiJG51bGwudmFsdWVbaV0+PW1pbnRlc3QpIHsgIAogICAgICB0ZXN0PC1wcm9wLnRlc3QoeD10YWIkc3VjY2Vzc1tpXSxuPXRhYiR0cmlhbFtpXSwgcD10YWIkbnVsbC52YWx1ZVtpXSwgCiAgICAgICAgICAgICAgICAgICAgICBhbHRlcm5hdGl2ZSA9ICJncmVhdGVyIikKICAgICAgdGFiJGNoaTJbaV08LXJvdW5kKHRlc3Qkc3RhdGlzdGljLDIpCiAgICAgIHRhYiRwLnZhbHVlW2ldPC1yb3VuZCh0ZXN0JHAudmFsdWUsNSkKICAgIH0gCiAgfQogIH0KICByZXR1cm4odGFiKQp9CgpgYGAKCgoKCmBgYHtyfQpoYyA8LSByZWFkUkRTKCJkYXRhL2NvcnB1cy9oY19teWNvcnB1c19zdGF0ZXNfcGFuZC5SRFMiKQpgYGAKCgojIyBUb3BpYyBmcmVxdWVuY2UgKFdoYXQgPykgCgoKIyMjIEZ1bmN0aW9uCgpgYGB7cn0KIyMjIC0tLS0tLS0tLS0tLS0tLS0gd2hhdCAtLS0tLS0tLS0tLS0tLS0tCiMnIEB0aXRsZSAgQ29tcHV0ZSB0aGUgYXZlcmFnZSBzYWxpZW5jZSBvZiB0aGUgdG9waWMKIycgQG5hbWUgd2hhdAojJyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGFibGUgYW5kIGdyYXBoaWMgb2YgdGhlIHRvcGljCiMnIEBwYXJhbSBoYyBhbiBoeXBlcmN1YmUgcHJlcGFyZWQgYXMgZGF0YS50YWJsZQojJyBAcGFyYW0gc3VidG9wIGEgc3VidGFnIG9mIHRoZSBtYWluIHRhZyAoZGVmYXVsdCA9IE5BKQojJyBAcGFyYW0gdGl0bGUgVGl0bGUgb2YgdGhlIGdyYXBoaWMKCgp3aGF0IDwtIGZ1bmN0aW9uIChoYyA9IGh5cGVyY3ViZSwKICAgICAgICAgICAgICAgICAgc3VidG9wID0gTkEsCiAgICAgICAgICAgICAgICAgIHRpdGxlID0gIldoYXQgPyIpCnsKIAogIAp0YWI8LWhjCmlmIChpcy5uYShzdWJ0b3ApKXt0YWIkd2hhdCA8LXRhYiR3aGF0ICE9Il9ub18ifWVsc2Uge3RhYiR3aGF0IDwtIHRhYiR3aGF0ID09IHN1YnRvcH0KCnRhYjwtdGFiWyxsaXN0KG5ld3MgPSBzdW0obmV3cykpLGJ5ID0gd2hhdF0KdGFiJHBjdDwtMTAwKnRhYiRuZXdzL3N1bSh0YWIkbmV3cykKCnAgPC0gcGxvdF9seSh0YWIsCiAgICAgICAgICAgICBsYWJlbHMgPSB+d2hhdCwKICAgICAgICAgICAgIHZhbHVlcyA9IH5wY3QsCiAgICAgICAgICAgICB0eXBlID0gJ3BpZScpICU+JQogIGxheW91dCh0aXRsZSA9IHRpdGxlLAogICAgICAgICB4YXhpcyA9IGxpc3Qoc2hvd2dyaWQgPSBGQUxTRSwgemVyb2xpbmUgPSBGQUxTRSwgc2hvd3RpY2tsYWJlbHMgPSBGQUxTRSksCiAgICAgICAgIHlheGlzID0gbGlzdChzaG93Z3JpZCA9IEZBTFNFLCB6ZXJvbGluZSA9IEZBTFNFLCBzaG93dGlja2xhYmVscyA9IEZBTFNFKSkKCm91dHB1dDwtbGlzdCgidGFibGUiID0gdGFiLCAicGxvdGx5IiA9cCkKCnJldHVybihvdXRwdXQpCgp9CmBgYAoKCiMjIyBFeGFtcGxlCgpgYGB7ciB3aGF0IGV4YW1wbGUgLHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpyZXNfd2hhdCA8LSB3aGF0KGhjID0gaGMsCiAgICAgICAgICAgICBzdWJ0b3AgPSBOQSwKICAgICAgICAgICAgIHRpdGxlID0gIlRvcGljIG5ld3MiKQpyZXNfd2hhdCR0YWJsZQpyZXNfd2hhdCRwbG90bHkKYGBgCgoKCgoKCgoKCgoKIyMgVG9waWMgdmFyaWF0aW9uIGJ5IG1lZGlhICh3aG8ud2hhdCkKClRoZSBmdW5jdGlvbiB3aG8ud2hhdCBleHBsb3JlIHRoZSB2YXJpYXRpb24gb2YgaW50ZXJlc3QgZm9yIHRoZSB0b3BpYyBpbiB0aGUgZGlmZmVyZW50IG1lZGlhIG9mIHRoZSBjb3JwdXMuCgojIyMgRnVuY3Rpb24KCmBgYHtyfQoKIyMjIyAtLS0tLS0tLS0tLS0tLS0tIHdoby53aGF0IC0tLS0tLS0tLS0tLS0tLS0KIycgQHRpdGxlICB2aXN1YWxpemUgdmFyaWF0aW9uIG9mIHRoZSB0b3BpYyBiZXR3ZWVuIG1lZGlhCiMnIEBuYW1lIHdoby53aGF0CiMnIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSB0YWJsZSBvZiB2YXJpYXRpb24gb2YgdGhlIHRvcGljIGJ5IG1lZGlhCiMnIEBwYXJhbSBoYyBhbiBoeXBlcmN1YmUgcHJlcGFyZWQgYXMgZGF0YS50YWJsZQojJyBAcGFyYW0gdGVzdCA6IHZpc3VhbGl6ZSB0ZXN0IChUUlVFKSBvciBzYWxpZW5jZSAoRkFMU0UpCiMnIEBwYXJhbSBtaW5zYW1wIDogVGhyZXNob2xkIG9mIHNhbXBsZSBzaXplIHJlcXVlc3RlZCBmb3Igc2FsaWVuY2UgY29tcHV0YXRpb24KIycgQHBhcmFtIG1pbnRlc3Qgc2FtcGxlIHNpemUgb2YgZXN0aW1hdGUgZm9yIGNoaS1zcXVhcmUgdGVzdCAoZGVmYXVsdCA9IDUpCiMnIEBwYXJhbSB0aXRsZSBUaXRsZSBvZiB0aGUgZ3JhcGhpYwoKCndoby53aGF0IDwtIGZ1bmN0aW9uIChoYyA9IGh5cGVyY3ViZSwKICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIG1pbnNhbXAgPSAyMCwKICAgICAgICAgICAgICAgICAgICAgIG1pbnRlc3QgPSA1LAogICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiV2hvIHNheXMgV2hhdCA/IikKewogIAogIHRhYjwtaGMKICB7dGFiJHdoYXQgPC10YWIkd2hhdCAhPSJfbm9fIn0KICAKICB0YWI8LXRhYlssbGlzdCh0cmlhbCA9IHN1bShuZXdzKSxzdWNjZXNzPXJvdW5kKHN1bShuZXdzKndoYXQpLDApKSxieSA9IGxpc3Qod2hvKV0KICByZWYgPC1yb3VuZChzdW0odGFiJHN1Y2Nlc3MpL3N1bSh0YWIkdHJpYWwpLDQpCiAgdGFiJG51bGwudmFsdWU8LXJlZgogIAogIHRhYjwtdGVzdGNoaTIodGFidGVzdD10YWIsCiAgICAgICAgICAgICAgICBtaW5zYW1wID0gbWluc2FtcCwKICAgICAgICAgICAgICAgIG1pbnRlc3QgPSBtaW50ZXN0KQogIAogIAogIAogIGlmICh0ZXN0PT1GQUxTRSkge3RhYiRpbmRleCA9dGFiJHNhbGllbmNlCiAgdGFiPC10YWJbdGFiJHRyaWFsID4gbWluc2FtcCxdCiAgbXljb2w8LWJyZXdlci5wYWwoNywiWWxPclJkIikKICB9IAogIGVsc2Uge3RhYiRpbmRleD10YWIkcC52YWx1ZQogIHRhYjwtdGFiW3RhYiR0cmlhbCp0YWIkbnVsbC52YWx1ZT5taW50ZXN0LF0KICBteWNvbDwtYnJld2VyLnBhbCg3LCJSZFlsQnUiKQogIG15Y29sWzRdPC0ibGlnaHR5ZWxsb3ciCiAgfQogIAogIHAgPC0gcGxvdF9seSh0YWIsCiAgICAgICAgICAgICAgIHggPSB+d2hvLAogICAgICAgICAgICAgICB5ID0gfmVzdGltYXRlKjEwMCwKICAgICAgICAgICAgICAgY29sb3I9IH5pbmRleCwKICAgICAgICAgICAgICAgY29sb3JzPSBteWNvbCwKICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInRleHQiLAogICAgICAgICAgICAgICB0ZXh0ID0gfnBhc3RlKCdTb3VyY2U6ICcsd2hvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gVG90YWwgbmV3cyAgOiAnLCByb3VuZCh0cmlhbCwwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyIC8+IFRvcGljIG5ld3MgOiAnLCByb3VuZChzdWNjZXNzLDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gJSBvYnNlcnZlZCAgOiAnLCByb3VuZChlc3RpbWF0ZSoxMDAsMiksJyUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gJSBlc3RpbWF0ZWQgOiAnLCByb3VuZChudWxsLnZhbHVlKjEwMCwyKSwnJScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBTYWxpZW5jZSA6ICcsIHJvdW5kKHNhbGllbmNlLDIpLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBwLnZhbHVlIDogJywgcm91bmQocC52YWx1ZSw0KSksCiAgICAgICAgICAgICAgIHR5cGUgPSAiYmFyIikgICU+JQogICAgbGF5b3V0KHRpdGxlID0gdGl0bGUsCiAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiUgbmV3cyIpLAogICAgICAgICAgIGJhcm1vZGUgPSAnc3RhY2snKQogIAogIG91dHB1dDwtbGlzdCgidGFibGUiID0gdGFiLCAicGxvdGx5IiA9cCkKICAKICByZXR1cm4ob3V0cHV0KQogIAp9CmBgYAoKCiMjIyBFeGFtcGxlCgoKYGBge3Igd2hvLndoYXQgZXhhbXBsZSx3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KCgoKCnJlc193aG9fd2hhdDwtIHdoby53aGF0KGhjPWhjLCAKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdCA9IFRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnNhbXAgPSA1LAogICAgICAgICAgICAgICAgICAgICAgICBtaW50ZXN0ID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVG9waWMgbmV3cyBieSBtZWRpYSAtIFNpZ25pZmljYW5jZSIpCnJlc193aG9fd2hhdCRwbG90bHkKCmBgYAoKCgojIyBUb3BpYyB2YXJpYXRpb24gdGhyb3VnaCB0aW1lICh3aGVuLndoYXQpCgoKCiMjIyBGdW5jdGlvbgoKYGBge3J9CiMjIyMgLS0tLS0tLS0tLS0tLS0tLSB3aGVuLndoYXQgLS0tLS0tLS0tLS0tLS0tLQojJyBAdGl0bGUgIHZpc3VhbGl6ZSB2YXJpYXRpb24gb2YgdGhlIHRvcGljIHRocm91Z2ggdGltZQojJyBAbmFtZSB3aGVuLndoYXQKIycgQGRlc2NyaXB0aW9uIGNyZWF0ZSBhIHRhYmxlIG9mIHZhcmlhdGlvbiBvZiB0aGUgdG9waWMgYnkgbWVkaWEKIycgQHBhcmFtIHRlc3QgOiB2aXN1YWxpemUgdGVzdCAoVFJVRSkgb3Igc2FsaWVuY2UgKEZBTFNFKQojJyBAcGFyYW0gbWluc2FtcCA6IFRocmVzaG9sZCBvZiBzYW1wbGUgc2l6ZSByZXF1ZXN0ZWQgZm9yIHNhbGllbmNlIGNvbXB1dGF0aW9uCiMnIEBwYXJhbSBtaW50ZXN0IHNhbXBsZSBzaXplIG9mIGVzdGltYXRlIGZvciBjaGktc3F1YXJlIHRlc3QgKGRlZmF1bHQgPSA1KQojJyBAcGFyYW0gdGl0bGUgVGl0bGUgb2YgdGhlIGdyYXBoaWMKCgp3aGVuLndoYXQgPC0gZnVuY3Rpb24gKGhjID0gaHlwZXJjdWJlLAogICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBtaW5zYW1wID0gMjAsCiAgICAgICAgICAgICAgICAgICAgICAgbWludGVzdCA9IDUsCiAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiV2hvIHNheXMgV2hhdCA/IikKewogIAogIHRhYjwtaGMKICB7dGFiJHdoYXQgPC10YWIkd2hhdCAhPSJfbm9fIn0KICAKICB0YWI8LXRhYlssbGlzdCh0cmlhbCA9IHN1bShuZXdzKSxzdWNjZXNzPXJvdW5kKHN1bShuZXdzKndoYXQpLDApKSxieSA9IGxpc3Qod2hlbildCiAgcmVmIDwtcm91bmQoc3VtKHRhYiRzdWNjZXNzKS9zdW0odGFiJHRyaWFsKSw0KQogIHRhYiRudWxsLnZhbHVlPC1yZWYKICAKICB0YWI8LXRlc3RjaGkyKHRhYnRlc3Q9dGFiLAogICAgICAgICAgICAgICAgbWluc2FtcCA9IG1pbnNhbXAsCiAgICAgICAgICAgICAgICBtaW50ZXN0ID0gbWludGVzdCkKICAKICBpZiAodGVzdD09RkFMU0UpIHt0YWIkaW5kZXggPXRhYiRzYWxpZW5jZQogIHRhYjwtdGFiW3RhYiR0cmlhbCA+IG1pbnNhbXAsXQogIG15Y29sPC1icmV3ZXIucGFsKDcsIllsT3JSZCIpCiAgfSAKICBlbHNlIHt0YWIkaW5kZXg9dGFiJHAudmFsdWUKICB0YWI8LXRhYlt0YWIkdHJpYWwqdGFiJG51bGwudmFsdWU+bWludGVzdCxdCiAgbXljb2w8LWJyZXdlci5wYWwoNywiUmRZbEJ1IikKICBteWNvbFs0XTwtImxpZ2h0eWVsbG93IgogIH0KICAKICAKICBwIDwtIHBsb3RfbHkodGFiLAogICAgICAgICAgICAgICB4ID0gfmFzLmNoYXJhY3Rlcih3aGVuKSwKICAgICAgICAgICAgICAgeSA9IH5lc3RpbWF0ZSoxMDAsCiAgICAgICAgICAgICAgIGNvbG9yPSB+aW5kZXgsCiAgICAgICAgICAgICAgIGNvbG9ycz0gbXljb2wsCiAgICAgICAgICAgICAgIGhvdmVyaW5mbyA9ICJ0ZXh0IiwKICAgICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgnVGltZTogJyx3aGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gVG90YWwgbmV3cyAgOiAnLCByb3VuZCh0cmlhbCwwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyIC8+IFRvcGljIG5ld3MgOiAnLCByb3VuZChzdWNjZXNzLDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gJSBvYnNlcnZlZCAgOiAnLCByb3VuZChlc3RpbWF0ZSoxMDAsMiksJyUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gJSBlc3RpbWF0ZWQgOiAnLCByb3VuZChudWxsLnZhbHVlKjEwMCwyKSwnJScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBTYWxpZW5jZSA6ICcsIHJvdW5kKHNhbGllbmNlLDIpLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBwLnZhbHVlIDogJywgcm91bmQocC52YWx1ZSw0KSksCiAgICAgICAgICAgICAgIHR5cGUgPSAiYmFyIikgICU+JQogICAgbGF5b3V0KHRpdGxlID0gdGl0bGUsCiAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIiUgbmV3cyIpLAogICAgICAgICAgIGJhcm1vZGUgPSAnc3RhY2snKQogIAogIG91dHB1dDwtbGlzdCgidGFibGUiID0gdGFiLCAicGxvdGx5IiA9cCkKICAKICByZXR1cm4ob3V0cHV0KQogIAp9CmBgYAoKCgojIyMgRXhhbXBsZSAxIDogMjAxOS0yMDIwICBieSBtb250aAoKCmBgYHtyIHdoZW4ud2hhdCBleGFtcGxlMSx3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KIyBNb2RpZnkgdGltZSBwZXJpb2QgYnkgbW9udGgKaGMyIDwtIGhjICU+JSBtdXRhdGUod2hlbiA9IGN1dCh3aGVuLGJyZWFrcz0ibW9udGgiKSkKCgpyZXNfd2hlbl93aGF0PC0gd2hlbi53aGF0KGhjPWhjMiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdD1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnNhbXA9MTAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWludGVzdD01LAogICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIlRvcGljIG5ld3MgYnkgbW9udGggLSBTaWduaWZpY2FuY2UiKQoKCnJlc193aGVuX3doYXQkcGxvdGx5CmBgYAoKCgojIyMgRXhhbXBsZSAyIDogMjAyMCAgYnkgd2VlawoKYGBge3Igd2hlbi53aGF0IGV4YW1wbGUyLHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQojIE1vZGlmeSB0aW1lIHBlcmlvZCBieSBtb250aApoYzIgPC0gaGMgJT4lIGZpbHRlcihzdWJzdHIod2hlbiwxLDQpPT0iMjAyMCIpICU+JSBtdXRhdGUod2hlbiA9IGN1dCh3aGVuLGJyZWFrcz0id2VlayIpKQoKCnJlc193aGVuX3doYXQ8LSB3aGVuLndoYXQoaGM9aGMyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXN0PVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWluc2FtcD0xMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBtaW50ZXN0PTUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVG9waWMgbmV3cyBieSB3ZWVrIC0gU2lnbmlmaWNhbmNlIikKCgpyZXNfd2hlbl93aGF0JHBsb3RseQpgYGAKCiMjIyBFeGFtcGxlIDMgOiBKYW4tTWFyY2ggMjAyMCBieSBkYXkKCmBgYHtyIHdoZW4ud2hhdCBleGFtcGxlMyx3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KIyBNb2RpZnkgdGltZSBwZXJpb2QgYnkgbW9udGgKaGMyIDwtIGhjICU+JSBmaWx0ZXIod2hlbiA+IGFzLkRhdGUoIjIwMjAtMDEtMDEiKSwgd2hlbiA8IGFzLkRhdGUoIjIwMjAtMDQtMDEiKSkgCgoKcmVzX3doZW5fd2hhdDwtIHdoZW4ud2hhdChoYz1oYzIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3Q9VFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5zYW1wPTEwLAogICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnRlc3Q9NSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJUb3BpYyBuZXdzIGJ5IGRheSAtIFNpZ25pZmljYW5jZSIpCgoKcmVzX3doZW5fd2hhdCRwbG90bHkKYGBgCgoKCgojIyBUb3BpYyB2YXJpYXRpb24gdGhyb3VnaCBzcGFjZSAod2hlcmUud2hhdCkKCgojIyMgRnVuY3Rpb24KCmBgYHtyfQoKIyMjIyAtLS0tLS0tLS0tLS0tLS0tIHdoZXJlLndoYXQgLS0tLS0tLS0tLS0tLS0tLQojJyBAdGl0bGUgIHZpc3VhbGl6ZSBzcGF0aWFsaXphdGlvbiBvZiB0aGUgdG9waWMgCiMnIEBuYW1lIHdoZXJlLndoYXQKIycgQGRlc2NyaXB0aW9uIGNyZWF0ZSBhIHRhYmxlIG9mIHZhcmlhdGlvbiBvZiB0aGUgdG9waWMgYnkgbWVkaWEKIycgQHBhcmFtIGhjIGFuIGh5cGVyY3ViZSBwcmVwYXJlZCBhcyBkYXRhLnRhYmxlCiMnIEBwYXJhbSB0ZXN0IDogdmlzdWFsaXplIHRlc3QgKFRSVUUpIG9yIHNhbGllbmNlIChGQUxTRSkKIycgQHBhcmFtIG1pbnNhbXAgOiBUaHJlc2hvbGQgb2Ygc2FtcGxlIHNpemUgcmVxdWVzdGVkIGZvciBzYWxpZW5jZSBjb21wdXRhdGlvbgojJyBAcGFyYW0gbWludGVzdCBzYW1wbGUgc2l6ZSBvZiBlc3RpbWF0ZSBmb3IgY2hpLXNxdWFyZSB0ZXN0IChkZWZhdWx0ID0gNSkKIycgQHBhcmFtIG1hcCBhIG1hcCB3aXRoIGNvb3JkaW5hdGVzIGluIGxhdC1sb25nCiMnIEBwYXJhbSBwcm9qIGEgcHJvamVjdGlvbiBhY2NlcHRlZCBieSBwbG90bHkKIycgQHBhcmFtIHRpdGxlIFRpdGxlIG9mIHRoZSBncmFwaGljCgoKd2hlcmUud2hhdCA8LSBmdW5jdGlvbiAoaGMgPSBoeXBlcmN1YmUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgbWluc2FtcCA9IDIwLAogICAgICAgICAgICAgICAgICAgICAgICBtaW50ZXN0ID0gNSwKICAgICAgICAgICAgICAgICAgICAgICAgbWFwID0gd29ybGRfY3RyLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9qID0gJ2F6aW11dGhhbCBlcXVhbCBhcmVhJywKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiV2hlcmUgc2FpZCBXaGF0ID8iKQp7CiAgCiAgdGFiPC1oYwogIHRhYiR3aGF0IDwtdGFiJHdoYXQgIT0iX25vXyIKICAKICB0YWI8LXRhYlssbGlzdCh0cmlhbCA9IHJvdW5kKHN1bShuZXdzKSwwKSxzdWNjZXNzPXJvdW5kKHN1bShuZXdzKndoYXQpLDApKSxieSA9IGxpc3Qod2hlcmUxKV0KICByZWYgPC1yb3VuZChzdW0odGFiJHN1Y2Nlc3MpL3N1bSh0YWIkdHJpYWwpLDQpCiAgdGFiJG51bGwudmFsdWU8LXJlZgogIAogIHRhYjwtdGVzdGNoaTIodGFidGVzdD10YWIsCiAgICAgICAgICAgICAgICBtaW5zYW1wID0gbWluc2FtcCwKICAgICAgICAgICAgICAgIG1pbnRlc3QgPSBtaW50ZXN0KQogIAogIAogIAogIHRhYjwtdGFiW29yZGVyKC1jaGkyKSxdCiAgCiAgCiAgCiAgaWYgKHRlc3Q9PUZBTFNFKSB7dGFiJGluZGV4ID10YWIkc2FsaWVuY2UKICB0YWI8LXRhYlt0YWIkdHJpYWwgPiBtaW5zYW1wLF0KICBteWNvbDwtYnJld2VyLnBhbCg3LCJZbE9yUmQiKQogIH0gCiAgZWxzZSB7dGFiJGluZGV4PXRhYiRwLnZhbHVlCiAgdGFiPC10YWJbdGFiJHRyaWFsKnRhYiRudWxsLnZhbHVlPm1pbnRlc3QsXQogIG15Y29sPC1icmV3ZXIucGFsKDcsIlJkWWxCdSIpCiAgbXljb2xbNF08LSJsaWdodHllbGxvdyIKICB9CiAgCiAgCiAgbWFwPC1tZXJnZShtYXAsdGFiLGFsbC54PVQsYWxsLnk9RixieS54PSJJU08zIixieS55PSJ3aGVyZTEiKQogIAogIAogIAogICNtYXAyPC1tYXBbaXMubmEobWFwJHBjdCk9PUYsXQogICNtYXAyPC1zdF9jZW50cm9pZChtYXAyKQogICNtYXAyPC1zdF9kcm9wX2dlb21ldHJ5KG1hcDIpCiAgCiAgCiAgZyA8LSBsaXN0KHNob3dmcmFtZSA9IFRSVUUsCiAgICAgICAgICAgIGZyYW1lY29sb3I9IHRvUkdCKCJncmF5MjAiKSwKICAgICAgICAgICAgY29hc3RsaW5lY29sb3IgPSB0b1JHQigiZ3JheTIwIiksCiAgICAgICAgICAgIHNob3dsYW5kID0gVFJVRSwKICAgICAgICAgICAgbGFuZGNvbG9yID0gdG9SR0IoImdyYXk1MCIpLAogICAgICAgICAgICBzaG93Y291bnRyaWVzID0gVFJVRSwKICAgICAgICAgICAgY291bnRyeWNvbG9yID0gdG9SR0IoIndoaXRlIiksCiAgICAgICAgICAgIGNvdW50cnl3aWR0aCA9IDAuMiwKICAgICAgICAgICAgcHJvamVjdGlvbiA9IGxpc3QodHlwZSA9IHByb2opKQogIAogIAogIAogIHA8LSBwbG90X2dlbyhtYXApJT4lCiAgICBhZGRfbWFya2Vycyh4ID0gfmxvbiwKICAgICAgICAgICAgICAgIHkgPSB+bGF0LAogICAgICAgICAgICAgICAgc2l6ZXMgPSBjKDAsIDI1MCksCiAgICAgICAgICAgICAgICBzaXplID0gfnN1Y2Nlc3MsCiAgICAgICAgICAgICAgICAjICAgICAgICAgICAgIGNvbG9yPSB+c2lnbmlmLAogICAgICAgICAgICAgICAgY29sb3IgPSB+aW5kZXgsCiAgICAgICAgICAgICAgICBjb2xvcnM9IG15Y29sLAogICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gInRleHQiLAogICAgICAgICAgICAgICAgdGV4dCA9IH5wYXN0ZSgnTG9jYXRpb246ICcsTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBUb3RhbCBuZXdzICA6ICcsIHJvdW5kKHRyaWFsLDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyIC8+IFRvcGljIG5ld3MgOiAnLCByb3VuZChzdWNjZXNzLDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyIC8+ICUgb2JzZXJ2ZWQgIDogJywgcm91bmQoZXN0aW1hdGUqMTAwLDIpLCclJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiAlIGVzdGltYXRlZCA6ICcsIHJvdW5kKG51bGwudmFsdWUqMTAwLDIpLCclJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxiciAvPiBTYWxpZW5jZSA6ICcsIHJvdW5kKHNhbGllbmNlLDIpLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnIgLz4gcC52YWx1ZSA6ICcsIHJvdW5kKHAudmFsdWUsNCkpKSAlPiUKICAgIAogICAgbGF5b3V0KGdlbyA9IGcsCiAgICAgICAgICAgdGl0bGUgPSB0aXRsZSkKICAKICAKICAKICBvdXRwdXQ8LWxpc3QoInRhYmxlIiA9IHRhYiwgInBsb3RseSIgPXApCiAgCiAgcmV0dXJuKG91dHB1dCkKICAKfQpgYGAKCgoKIyMjIEV4YW1wbGUKCgpgYGB7ciB3aGVyZS53aGF0IGV4YW1wbGUsd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9Cm1hcDwtcmVhZFJEUygiZGF0YS9kaWNvX3N0YXRlcy93b3JsZF9jdHJfNDMyNi5SZGF0YSIpCmhjMjwtaGMgJT4lIGZpbHRlcih3aGVyZTEgIT0iX25vXyIsIHdoZXJlMiAhPSJfbm9fIikgJT4lIGZpbHRlcih3aGVyZTEgIT0iR0JSIiwgd2hlcmUyICE9IkdCUiIpCgpyZXNfd2hlcmVfd2hhdDwtIHdoZXJlLndoYXQoaGM9aGMyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVzdD1UUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWluc2FtcD0xMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcCA9IG1hcCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW50ZXN0ID0yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiVG9waWMgbmV3cyBieSBzdGF0ZXMgLSBTaWduaWZpY2FuY2UiKQpyZXNfd2hlcmVfd2hhdCRwbG90bHkKYGBgCgoKCiMgU3BhdGlhbCBOZXR3b3JrcwoKCgoKIyMgR2VvIG5ldHdvcmtzIG1vZGVsaXNhdGlvbgoKCiMjIyBIeXBlcmN1YmUgRmlsdGVyIChmdW5jdGlvbikKCgpgYGB7cn0KaGNfZmlsdGVyIDwtIGZ1bmN0aW9uKGRvbiA9IGhjLAogICAgICAgICAgICAgICAgICAgICAgd2hvID0gIndobyIsCiAgICAgICAgICAgICAgICAgICAgICB3aGVuID0gIndoZW4iLAogICAgICAgICAgICAgICAgICAgICAgd2hlcmUxID0gIndoZXJlMSIsCiAgICAgICAgICAgICAgICAgICAgICB3aGVyZTIgPSAid2hlcmUyIiwKICAgICAgICAgICAgICAgICAgICAgIHdndCA9ICJ0YWdzIiwKICAgICAgICAgICAgICAgICAgICAgIHNlbGYgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIHdoZW5fc3RhcnQgPSBOQSwKICAgICAgICAgICAgICAgICAgICAgIHdoZW5fZW5kID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aG9fZXhjID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aG9faW5jID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aGVyZTFfZXhjID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aGVyZTFfaW5jID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aGVyZTJfZXhjID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICB3aGVyZTJfaW5jID0gTkEpCgogIHsgICAgICAgICAgICAgICAgICAgICAgICAgIAogIAogICAgZGY8LWRhdGEudGFibGUod2hvID0gZG9uW1t3aG9dXSwKICAgICAgICAgICAgICAgICAgIHdoZW4gPSBkb25bW3doZW5dXSwKICAgICAgICAgICAgICAgICAgIHdoZXJlMSA9IGRvbltbd2hlcmUxXV0sCiAgICAgICAgICAgICAgICAgICB3aGVyZTIgPSBkb25bW3doZXJlMl1dLAogICAgICAgICAgICAgICAgICAgd2d0ID0gZG9uW1t3Z3RdXSkKICAgIAogICAgIyBTZWxlY3QgdGltZSBwZXJpb2QKICAgICAgICBpZiAoaXMubmEod2hlbl9zdGFydCk9PUZBTFNFKSB7IAogICAgICAgIGRmIDwtIGRmW3doZW4gPj0gYXMuRGF0ZSh3aGVuX3N0YXJ0KSwgXX0KICAgICAgICBpZiAoaXMubmEod2hlbl9lbmQpPT1GQUxTRSkgeyAKICAgICAgICBkZiA8LSBkZlt3aGVuIDw9IGFzLkRhdGUod2hlbl9lbmQpLCBdfQogICAgIyBTZWxlY3Qgd2hvCiAgICAgICAgaWYgKGlzLm5hKHdob19leGMpPT1GQUxTRSkgeyAKICAgICAgICBkZiA8LSBkZlshKHdobyAlaW4lIHdob19leGMpLCBdfQogICAgICAgIGlmIChpcy5uYSh3aG9faW5jKT09RkFMU0UpIHsgCiAgICAgICAgZGYgPC0gZGZbKHdobyAlaW4lIHdob19pbmMpLCBdfQogICAgIyBTZWxlY3Qgd2hlcmUxCiAgICAgICAgaWYgKGlzLm5hKHdoZXJlMV9leGMpPT1GQUxTRSkgeyAKICAgICAgICBkZiA8LSBkZlshKHdoZXJlMSAlaW4lIHdoZXJlMV9leGMpLCBdfQogICAgICAgIGlmIChpcy5uYSh3aGVyZTFfaW5jKT09RkFMU0UpIHsgCiAgICAgICAgZGYgPC0gZGZbKHdoZXJlMSAlaW4lIHdoZXJlMV9pbmMpLCBdfQogICAgIyBTZWxlY3Qgd2hlcmUyCiAgICAgICAgaWYgKGlzLm5hKHdoZXJlMl9leGMpPT1GQUxTRSkgeyAKICAgICAgICBkZiA8LSBkZlshKHdoZXJlMiAlaW4lIHdoZXJlMl9leGMpLCBdfQogICAgICAgIGlmIChpcy5uYSh3aGVyZTJfaW5jKT09RkFMU0UpIHsgCiAgICAgICAgZGYgPC0gZGZbKHdoZXJlMiAlaW4lIHdoZXJlMl9pbmMpLCBdfQogICAgIyBlbGltaW5hdGUgaW50ZXJuYWwgbGlua3MKICAgICAgIGlmIChzZWxmPT1GQUxTRSkgeyAKICAgICAgICBkZiA8LSBkZlsod2hlcmUxICE9IHdoZXJlMiksIF19CiAgICByZXR1cm4oZGYpCiAgCn0KYGBgCgojIyMgTWF0cml4IGJ1aWxkZXIgKGZ1bmN0aW9uKQoKCgoKYGBge3J9CmJ1aWxkX2ludCA8LSBmdW5jdGlvbihkb24gPSBkb24sICAgICAgICMgYSBkYXRhZnJhbWUgd2l0aCBjb2x1bW5zIGksIGogLCBGaWoKICAgICAgICAgICAgICAgICAgICAgIGkgPSAid2hlcmUxIiwKICAgICAgICAgICAgICAgICAgICAgIGogPSAid2hlcmUyIiwKICAgICAgICAgICAgICAgICAgICAgIEZpaiA9ICJ3Z3QiLAogICAgICAgICAgICAgICAgICAgICAgczEgPSAxMCwKICAgICAgICAgICAgICAgICAgICAgIHMyID0gMTAsCiAgICAgICAgICAgICAgICAgICAgICBuMSA9IDIsCiAgICAgICAgICAgICAgICAgICAgICBuMiA9IDIsCiAgICAgICAgICAgICAgICAgICAgICBrID0gMSkKCnsgIAogIGRmPC1kYXRhLnRhYmxlKGk9ZG9uW1tpXV0saj1kb25bW2pdXSxGaWo9ZG9uW1tGaWpdXSkKICBpbnQgPC1kZlssLihGaWo9c3VtKEZpaikpLC4oaSxqKV0KICBpbnQ8LWRjYXN0KGludCxmb3JtdWxhID0gaX5qLGZpbGwgPSAwKQogIG1hdDwtYXMubWF0cml4KGludFssLTFdKQogIHJvdy5uYW1lcyhtYXQpPC1pbnQkaQogIG1hdDwtbWF0W2FwcGx5KG1hdCwxLHN1bSk+PXMxLGFwcGx5KG1hdCwyLHN1bSk+PXMyIF0KICBtMDwtbWF0CiAgbTBbbTA8a108LTAKICBtMFttMD49a108LTEKICBtYXQ8LW1hdFthcHBseShtMCwxLHN1bSk+PW4xLGFwcGx5KG0wLDIsc3VtKT49bjIgXQogIGludDwtcmVzaGFwZTI6Om1lbHQobWF0KQogIG5hbWVzKGludCkgPC1jKCJpIiwiaiIsIkZpaiIpCiAgcmV0dXJuKGludCkKfQoKYGBgCgoKIyMjIFJhbmRvbSBtb2RlbCAoZnVuY3Rpb24pCgoKYGBge3J9CgpyYW5kX2ludCA8LSBmdW5jdGlvbihpbnQgPSBpbnQsICMgQSB0YWJsZSB3aXRoIGNvbHVtbnMgaSwgaiBGaWoKICAgICAgICAgICAgICAgICAgICAgbWF4c2l6ZSA9IDEwMDAwMCwKICAgICAgICAgICAgICAgICAgICAgZGlhZyAgICA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICByZXNpZCAgID0gRkFMU0UpIHsKICAgICMgRWxpbWluYXRlIGRpYWdvbmFsID8KICAgIGlmIChkaWFnPT1GQUxTRSkgeyAKICAgICAgICBpbnQgPC0gaW50W2FzLmNoYXJhY3RlcihpbnQkaSkgIT0gYXMuY2hhcmFjdGVyKGludCRqKSwgXX0KICAKICAgICMgQ29tcHV0ZSBtb2RlbCBpZiBzaXplIG5vdCB0b28gbGFyZ2UKICAgIGlmIChkaW0oaW50KVsxXSA8IG1heHNpemUpIHsKICAgICAgICMgUHJvY2VlZCB0byBwb2lzc29uIHJlZ3Jlc3Npb24gbW9kZWwKICAgICAgIG1vZCA8LSBnbG0oIGZvcm11bGEgPSBGaWogfiBpICsgaixmYW1pbHkgPSAicG9pc3NvbiIsIGRhdGEgPSBpbnQpCiAgCiAgICAgICAjIEFkZCByZXNpZHVhbHMgaWYgcmVxdWVzdGVkCiAgICAgICBpZihyZXNpZCA9PSBUUlVFKSAgIHsgCiAgICAgICAgICAjIEFkZCBlc3RpbWF0ZXMKICAgICAgICAgIGludCRFaWogPC0gbW9kJGZpdHRlZC52YWx1ZXMKCiAgICAgICAgICAjIEFkZCBhYnNvbHV0ZSByZXNpZHVhbHMKICAgICAgICAgIGludCRSYWJzX2lqIDwtIGludCRGaWotaW50JEVpagoKICAgICAgICAgICMgQWRkIHJlbGF0aXZlIHJlc2lkdWFscwogICAgICAgICAgaW50JFJyZWxfaWogPC0gaW50JEZpai9pbnQkRWlqCgogICAgICAgICAgIyBBZGQgY2hpLXNxdWFyZSByZXNpZHVhbHMKICAgICAgICAgIGludCRSY2hpX2lqIDwtICAoaW50JFJhYnNfaWopKioyIC8gaW50JEVpagogICAgICAgICAgaW50JFJjaGlfaWpbaW50JFJhYnNfaWo8MF08LSAtaW50JFJjaGlfaWpbaW50JFJhYnNfaWo8MF0KICAgICAgICAgIH0KICAgICAgICAgCiAgICB9IGVsc2UgeyBwYXN0ZSAoIlRhYmxlID4gMTAwMDAwIC0gIFxuIAogICAgICAgICAgICAgICAgICAgICBtb2RpZnkgbWF4c2l6ZSA9ICBwYXJhbWV0ZXIgXG4KICAgICAgICAgICAgICAgICAgICAgaWYgeW91IGFyZSBzdXJlIHRoYXQgeW91ciBjb21wdXRlciBjYW4gZG8gaXQgISIpfQogICMgRXhwb3J0IHJlc3VsdHMKICBpbnQkaTwtYXMuY2hhcmFjdGVyKGludCRpKQogIGludCRqPC1hcy5jaGFyYWN0ZXIoaW50JGopCiAgcmV0dXJuKGludCkKICAKIH0KCmBgYAoKCiMjIyBWaXN1YWxpemUgbmV0d29yayAoZnVuY3Rpb24pCgpgYGB7cn0KZ2VvX25ldHdvcms8LSBmdW5jdGlvbihkb24gPSBkb24sCiAgICAgICAgICAgICAgICAgICAgICAgZnJvbSA9ICJpIiwKICAgICAgICAgICAgICAgICAgICAgICAgdG8gPSAiaiIsIAogICAgICAgICAgICAgICAgICAgICAgICBzaXplID0gIkZpaiIsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pbnNpemUgPSAxLAogICAgICAgICAgICAgICAgICAgICAgICBtYXhzaXplID0gTkEsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3QgPSAiRmlqIiwKICAgICAgICAgICAgICAgICAgICAgICAgbWludGVzdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgIGxvb3BzICA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiTmV0d29yayIpCgp7CmludDwtZGF0YS5mcmFtZShpID0gYXMuY2hhcmFjdGVyKGRvblssZnJvbV0pLAogICAgICAgICAgICAgICAgaiA9IGFzLmNoYXJhY3Rlcihkb25bLHRvXSksCiAgICAgICAgICAgICAgICBzaXplID0gZG9uWyxzaXplXSwKICAgICAgICAgICAgICAgIHRlc3QgPSBkb25bLHRlc3RdCiAgICAgICAgICAgICAgICApCmlmIChpcy5uYShtaW5zaXplKT09RkFMU0UpIHtpbnQgPWludFtpbnQkc2l6ZSA+PSBtaW5zaXplLF19IAppZiAoaXMubmEobWF4c2l6ZSk9PUZBTFNFKSB7aW50ID1pbnRbaW50JHNpemUgPD0gbWF4c2l6ZSxdfSAKaWYgKGlzLm5hKG1pbnRlc3QpPT1GQUxTRSkge2ludCA9aW50W2ludCR0ZXN0ID49IG1pbnRlc3QsXX0KCm5vZGVzPC1kYXRhLmZyYW1lKGNvZGUgPSB1bmlxdWUoYyhpbnQkaSxpbnQkaikpKQpub2RlcyRjb2RlPC1hcy5jaGFyYWN0ZXIobm9kZXMkY29kZSkKbm9kZXMkaWQ8LTE6bGVuZ3RoKG5vZGVzJGNvZGUpCm5vZGVzJGxhYmVsPC1ub2RlcyRjb2RlCm5vZGVzJGNvbG9yIDwtImdyYXkiCm5vZGVzJGNvbG9yW25vZGVzJGNvZGUgJWluJSBpbnQkal08LSJyZWQiCgoKIyBBZGp1c3QgZWRnZSBjb2RlcwplZGdlcyA8LSBpbnQgJT4lIG11dGF0ZSh3aWR0aCA9IDUrNSpzaXplIC8gbWF4KHNpemUpKSAlPiUKICAgICAgICAgICAgICAgIGxlZnRfam9pbihub2RlcyAlPiUgc2VsZWN0KGk9Y29kZSwgZnJvbSA9IGlkKSkgJT4lICAKICAgICAgICAgICAgICAgIGxlZnRfam9pbihub2RlcyAlPiUgc2VsZWN0KGo9Y29kZSwgdG8gPSBpZCApKSAKCiMgY29tcHV0ZSBub2Rlc2l6ZQp0b3RpPC1pbnQgJT4lIGdyb3VwX2J5KGkpICU+JSBzdW1tYXJpemUoc2l6ZSA9c3VtKHNpemUpKSAlPiUgc2VsZWN0IChjb2RlPWksc2l6ZSkKdG90ajwtaW50ICU+JSBncm91cF9ieShqKSAlPiUgc3VtbWFyaXplKHNpemUgPXN1bShzaXplKSkgJT4lIHNlbGVjdCAoY29kZT1qLHNpemUpCnRvdDwtcmJpbmQodG90aSx0b3RqKQp0b3Q8LXVuaXF1ZSh0b3QpCnRvdCRjb2RlPC1hcy5mYWN0b3IodG90JGNvZGUpCm5vZGVzIDwtIGxlZnRfam9pbihub2Rlcyx0b3QpICU+JSBtdXRhdGUodmFsdWUgPSAxICs1KnNxcnQoc2l6ZS9tYXgoc2l6ZSkpKQoKCiNzZWxfbm9kZXMgPC1ub2RlcyAlPiUgZmlsdGVyKGNvZGUgJWluJSB1bmlxdWUoYyhzZWxfZWRnZXMkaSxzZWxfZWRnZXMkaikpKQoKIyBlbGltaW5hdGUgbG9vcHMKCmlmKGxvb3BzID09IEZBTFNFKSB7ZWRnZXMgPC0gZWRnZXNbZWRnZXMkZnJvbSA8IGVkZ2VzJHRvLF19CgpuZXQ8LSB2aXNOZXR3b3JrKG5vZGVzLCAKICAgICAgICAgICAgICAgICAgZWRnZXMsIAogICAgICAgICAgICAgICAgICBtYWluID0gdGl0bGUsCmhlaWdodCA9ICIxMDAwcHgiLCAKICAgICAgICAgICAgICAgICAgd2lkdGggPSAiNzAlIikgICAlPiUgICAKICAgdmlzTm9kZXMoc2NhbGluZyA9bGlzdChtaW4gPTIwLCBtYXg9NjAsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPWxpc3QobWluPTIwLG1heD04MCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heFZpc2libGUgPSAyMCkpKSU+JQogIHZpc0VkZ2VzKHNjYWxpbmcgPSBsaXN0KG1pbj0yMCxtYXg9NjApKSU+JQogICAgICAgdmlzT3B0aW9ucyhoaWdobGlnaHROZWFyZXN0ID0gVFJVRSwKICAgICAjICAgICAgICAgICAgICAgc2VsZWN0ZWRCeSA9ICJncm91cCIsIAogICAgIyAgICAgICAgICAgICAgIG1hbmlwdWxhdGlvbiA9IFRSVUUsCiAgICAgICAgICAgICAgICAgIG5vZGVzSWRTZWxlY3Rpb24gPSBUUlVFKSAlPiUKICAgICAgICB2aXNJbnRlcmFjdGlvbihuYXZpZ2F0aW9uQnV0dG9ucyA9IFRSVUUpICU+JQogICAgICAgICB2aXNMZWdlbmQoKSAlPiUKICAgICAgdmlzSWdyYXBoTGF5b3V0KGxheW91dCA9ImxheW91dC5mcnVjaHRlcm1hbi5yZWluZ29sZCIsc21vb3RoID0gVFJVRSkKCm5ldAogcmV0dXJuKG5ldCkKIH0gCgpgYGAKCgojIyBBcHBsaWNhdGlvbgoKCgpgYGB7cn0KIyBMb2FkIGNvbXBsZXRlIGh5cGVyY3ViZQpoYyA8LSByZWFkUkRTKCJkYXRhL2NvcnB1cy9oY19teWNvcnB1c19zdGF0ZXNfcGFuZC5SRFMiKQpoYyA8LSBoYyAlPiUgZmlsdGVyKHdoZXJlMSAhPSJfbm9fIiwgd2hlcmUyICE9ICJfbm9fIikKCiMgRWxpbWluYXRlIG5vbiBmb3JlaWduIG5ld3MgCiNoYzwtaGNbaGMkd2hlcmUxICE9IHN1YnN0cih3aG8sNCw2KSxdCiNoYzwtaGNbaGMkd2hlcmUyICE9IHN1YnN0cih3aG8sNCw2KSxdCgojIEFkZCBjb21wbGV0ZSBsYWJlbHMKbWFwPC1yZWFkUkRTKCJkYXRhL2RpY29fc3RhdGVzL3dvcmxkX21hcF80MzI2LlJkYXRhIikKbGFiczwtc3RfZHJvcF9nZW9tZXRyeShtYXApCmxhYnM8LWxhYnNbLGMoMSw0KV0KCiMgU2hvcnRlbiB0aGUgbmFtZSBvZiBVU0EKbGFicyROQU1FW2xhYnMkSVNPMz09IlVTQSJdPC0iVS5TLkEuIgoKCm5hbWVzKGxhYnMpPC1jKCJ3aGVyZTEiLCJnZW9mcjEiKQpoYzwtbGVmdF9qb2luKGhjLGxhYnMpCm5hbWVzKGxhYnMpPC1jKCJ3aGVyZTIiLCJnZW9mcjIiKQpoYzwtbGVmdF9qb2luKGhjLGxhYnMpCgpoY19nZW9fZ2VvIDwtIGhjCmBgYAoKCiMjIyBSZWZlcmVuY2UgbmV0d29yawoKCgpgYGB7cn0KaGM8LWhjX2dlb19nZW8gCgoKCmhjPC1oY19maWx0ZXIoZG9uID0gaGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2d0ID0gIm5ld3MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlMSA9ICJnZW9mcjEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlMiA9ICJnZW9mcjIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoZXJlMV9leGMgPSBjKCJfbm9fIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlcmUyX2V4YyA9IGMoIl9ub18iKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmID0gRkFMU0UKICAgICAgICAgICAgICAgICAgICAgICAgICAgKQoKaW50IDwtIGJ1aWxkX2ludChkb24gPSBoYywKICAgICAgICAgICAgICAgICBzMT0yLAogICAgICAgICAgICAgICAgIHMyPTIsCiAgICAgICAgICAgICAgICAgbjE9MSwKICAgICAgICAgICAgICAgICBuMj0xLAogICAgICAgICAgICAgICAgIGs9MCkKCm1vZDwtcmFuZF9pbnQoaW50LAogICAgICAgICAgICAgIHJlc2lkID0gVFJVRSwKICAgICAgICAgICAgICBkaWFnID0gRkFMU0UpCgoKbmV0d29yazwtIGdlb19uZXR3b3JrKG1vZCwKICAgICAgICAgICAgICAgICAgICAgIHNpemUgPSAiRmlqIiwKICAgICAgICAgICAgICAgICAgICAgIG1pbnNpemUgPSAxLAogICAgICAgICAgICAgICAgICAgICAgdGVzdCA9ICJSY2hpX2lqIiwKICAgICAgICAgICAgICAgICAgICAgIG1pbnRlc3QgPSAzLjg0KQpuZXR3b3JrCgpgYGAKCgo=